package com.piece.core.web.exception;

import com.piece.core.framework.constant.ExceptionConstants;
import com.piece.core.framework.exception.*;
import com.piece.core.framework.support.response.AjaxResponse;
import com.piece.core.framework.util.basic.I18nUtil;
import com.piece.core.web.util.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;

/**
 * 自定义异常处理器
 */
@Slf4j
//@RestControllerAdvice
public class RestExceptionHandler {

    /**
     * IllegalArgumentException异常处理返回json
     * 返回状态码:400
     */
    @ExceptionHandler({IllegalArgumentException.class})
    public AjaxResponse badRequestException(IllegalArgumentException e) {
        log.error("参数解析异常:", e);
        return AjaxResponse.error(HttpStatus.BAD_REQUEST.value(), I18nUtil.message(ExceptionConstants.ARGUMENT), e.getMessage());
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public AjaxResponse handleException(HttpRequestMethodNotSupportedException e) {
        log.error("请求方式不支持异常:", e);
        return AjaxResponse.error(HttpStatus.METHOD_NOT_ALLOWED.value(), I18nUtil.message(ExceptionConstants.METHOD, e.getMethod()), e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler({ServerException.class})
    public AjaxResponse businessException(ServerException e) {
        log.error("业务操作异常:", e);
        return AjaxResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), I18nUtil.message(ExceptionConstants.SERVER), e.getMessage());
    }

    /**
     * 不支持当前媒体类型
     */
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public AjaxResponse handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        log.error("不支持当前媒体类型:", e);
        return AjaxResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), I18nUtil.message(ExceptionConstants.MEDIA_TYPE), e.getMessage());
    }

    /**
     * 权限异常
     */
    @ExceptionHandler({PermissionException.class})
    public AjaxResponse handleException(PermissionException e) {
        log.error("权限异常:", e);
        return AjaxResponse.error(HttpStatus.FORBIDDEN.value(), I18nUtil.message(ExceptionConstants.PERMISSION), e.getMessage());
    }

    /**
     * 服务丢失异常
     */
    @ExceptionHandler({NotFoundException.class})
    public AjaxResponse noResultException(NotFoundException e) {
        log.error("服务丢失异常:", e);
        return AjaxResponse.error(HttpStatus.NOT_FOUND.value(), I18nUtil.message(ExceptionConstants.NOT_FOUND));
    }

    /**
     * 幂等性异常
     */
    @ExceptionHandler({IdempotencyException.class})
    public AjaxResponse idempotencyException(IdempotencyException e) {
        log.error("幂等性异常:", e);
        return AjaxResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), I18nUtil.message(ExceptionConstants.IDEMPOTENCY), e.getMessage());
    }

    /**
     * 演示模式异常
     */
    @ExceptionHandler({DemoModeException.class})
    public AjaxResponse demoModeException(DemoModeException e) {
        log.info("演示模式异常:", e);
        return AjaxResponse.error(HttpStatus.FORBIDDEN.value(), I18nUtil.message(ExceptionConstants.DEMO));
    }

    /**
     * 系统异常
     */
    @ExceptionHandler({FrameWorkException.class})
    public AjaxResponse frameworkException(DemoModeException e) {
        log.info("系统异常:", e);
        return AjaxResponse.error(HttpStatus.FORBIDDEN.value(), I18nUtil.message(ExceptionConstants.SERVER));
    }

    /**
     * 系统异常
     */
    @ExceptionHandler({RuntimeException.class})
    public Object handleRuntimeException(HttpServletRequest request, Exception e) {
        log.error("服务器异常:", e);
        if (ServletUtil.isAjaxRequest(request)) {
            return AjaxResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), I18nUtil.message(ExceptionConstants.RUNTIME), e.getMessage());
        }
        throw new RuntimeException(e);
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler({Exception.class})
    public Object handleException(HttpServletRequest request, RuntimeException e) {
        log.error("运行时异常:", e);
        if (ServletUtil.isAjaxRequest(request)) {
            return AjaxResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), I18nUtil.message(ExceptionConstants.RUNTIME), e.getMessage());
        }
        throw new RuntimeException(e);
    }
}
